package com.bandaotixi.cashier.api.common.util;

import cn.hutool.core.io.FileUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.bandaotixi.cashier.api.common.model.KeyValue;
import com.bandaotixi.cashier.api.common.model.KeyValue3;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.*;

public class RegionUtil {

    public static boolean isProvince(String code) {
        return codeProvinceCityDistrict.containsKey(code);
    }

    public static boolean isCity(String provinceCode, String code) {
        return codeProvinceCityDistrict.containsKey(provinceCode) && codeProvinceCityDistrict.get(provinceCode).containsKey(code);
    }

    public static boolean isDistrict(String provinceCode, String cityCode, String code) {
        return codeProvinceCityDistrict.containsKey(provinceCode) && codeProvinceCityDistrict.get(provinceCode).containsKey(cityCode) && codeProvinceCityDistrict.get(provinceCode).get(cityCode).containsKey(code);
    }

    public static boolean isProvinceName(String name) {
        return nameProvinceCityDistrict.containsKey(name);
    }

    public static boolean isCityName(String provinceName, String name) {
        return nameProvinceCityDistrict.containsKey(provinceName) && nameProvinceCityDistrict.get(provinceName).containsKey(name);
    }

    public static boolean isDistrictName(String provinceName, String cityName, String name) {
        return nameProvinceCityDistrict.containsKey(provinceName) && nameProvinceCityDistrict.get(provinceName).containsKey(cityName) && nameProvinceCityDistrict.get(provinceName).get(cityName).contains(name);
    }

    public static void checkName(String provinceName, String cityName, String name) {
        if (StringUtils.hasLength(provinceName) || StringUtils.hasLength(cityName) || StringUtils.hasLength(name)) {
            Assert.isTrue(isProvinceName(provinceName), "省份名称错误");
            Assert.isTrue(isCityName(provinceName, cityName), "城市名称错误");
            Assert.isTrue(isDistrictName(provinceName, cityName, name), "区名称错误");
        }
    }

    /**
     * 随机生成省市区
     */
    public static KeyValue3<String, String, String> random() {
        Random random = new Random();
        String provinceName = new ArrayList<>(nameProvinceCityDistrict.keySet()).get(random.nextInt(nameProvinceCityDistrict.size()));
        Set<String> cityNames = nameProvinceCityDistrict.get(provinceName).keySet();
        String cityName = new ArrayList<>(cityNames).get(random.nextInt(cityNames.size()));
        List<String> districtNames = nameProvinceCityDistrict.get(provinceName).get(cityName);
        String districtName = districtNames.get(random.nextInt(districtNames.size()));
        return KeyValue3.just(provinceName, cityName, districtName);
    }

    /**
     * 省、市、区名称关系
     */
    private static final Map<String, Map<String, List<String>>> nameProvinceCityDistrict = new HashMap<>();
    /**
     * 省、市、区代码关系
     */
    private static final Map<String, Map<String, Map<String, KeyValue<String, String>>>> codeProvinceCityDistrict = new HashMap<>();

    static {
        init();
    }

    private static void init() {
        File jsonFile = FileUtil.file("data/china-regions.json");
        Assert.isTrue(jsonFile.exists(), "JSON文件不存在 china-regions.json");
        String json = FileUtil.readString(jsonFile, StandardCharsets.UTF_8);
        JSONArray regions = JSONUtil.parseArray(json);
        for (int p = 0; p < regions.size(); p++) {
            JSONObject province = regions.getJSONObject(p);
            Map<String, List<String>> nameCityMap = nameProvinceCityDistrict.computeIfAbsent(province.getStr("name"), k -> new HashMap<>());
            Map<String, Map<String, KeyValue<String, String>>> codeCityMap = codeProvinceCityDistrict.computeIfAbsent(province.getStr("code"), k -> new HashMap<>());
            JSONArray cityList = province.getJSONArray("children");
            if (cityList != null) {
                for (int c = 0; c < cityList.size(); c++) {
                    JSONObject city = cityList.getJSONObject(c);
                    List<String> nameDistrictList = nameCityMap.computeIfAbsent(city.getStr("name"), k -> new ArrayList<>());
                    Map<String, KeyValue<String, String>> codeDistrictMap = codeCityMap.computeIfAbsent(city.getStr("code"), k -> new HashMap<>());
                    JSONArray districtList = city.getJSONArray("children");
                    if (districtList != null) {
                        for (int d = 0; d < districtList.size(); d++) {
                            JSONObject district = districtList.getJSONObject(d);
                            nameDistrictList.add(district.getStr("name"));
                            codeDistrictMap.put(district.getStr("code"), KeyValue.just(district.getStr("code"), district.getStr("name")));
                            Assert.isTrue(!district.containsKey("children"), "区域:" + district.getStr("name") + "的子级未解析");
                        }
                    }
                }
            }
        }
    }

    public static void main(String[] args) {
        System.out.println(nameProvinceCityDistrict);
    }
}
